#pragma once
#include <Windows.h>
#define INITGUID
#include <evntrace.h>
#include <evntcons.h>
#include <atlstr.h>
#include <tchar.h>
#include <tdh.h>
#include <string>

typedef enum _EVENT_FLAGS
{
    EVENT_FLAG_NONE = 0,
    EVENT_FLAG_PROCESS = EVENT_TRACE_FLAG_PROCESS,
    EVENT_FLAG_THREAD = EVENT_TRACE_FLAG_THREAD,
    EVENT_FLAG_IMAGE_LOAD = EVENT_TRACE_FLAG_IMAGE_LOAD,
    EVENT_FLAG_REGISTRY = EVENT_TRACE_FLAG_REGISTRY,
    EVENT_FLAG_DISKIO = EVENT_TRACE_FLAG_DISK_IO,
    EVENT_FLAG_DISKFILEIO = EVENT_TRACE_FLAG_DISK_FILE_IO,
    EVENT_FLAG_MEMORY_PAGE_FAULTS = EVENT_TRACE_FLAG_MEMORY_PAGE_FAULTS,
    EVENT_FLAG_MEMORY_HARD_FAULTS = EVENT_TRACE_FLAG_MEMORY_HARD_FAULTS,
    EVENT_FLAG_NETWORK_TCPIP = EVENT_TRACE_FLAG_NETWORK_TCPIP,
    EVENT_FLAG_DBGPRINT = EVENT_TRACE_FLAG_DBGPRINT,
    EVENT_FLAG_PROCESS_COUNTERS = EVENT_TRACE_FLAG_PROCESS_COUNTERS,
    EVENT_FLAG_CONTEXT_SWITCH = EVENT_TRACE_FLAG_CSWITCH,
    EVENT_FLAG_DPC = EVENT_TRACE_FLAG_DPC,
    EVENT_FLAG_INTERRUPT = EVENT_TRACE_FLAG_INTERRUPT,
    EVENT_FLAG_SYSTEMCALL = EVENT_TRACE_FLAG_SYSTEMCALL,
    EVENT_FLAG_DISKIO_INIT = EVENT_TRACE_FLAG_DISK_IO_INIT,
    EVENT_FLAG_ALPC = EVENT_TRACE_FLAG_ALPC,
    EVENT_FLAG_SPLIT_IO = EVENT_TRACE_FLAG_SPLIT_IO,
    EVENT_FLAG_DRIVER = EVENT_TRACE_FLAG_DRIVER,
    EVENT_FLAG_PROFILE = EVENT_TRACE_FLAG_PROFILE,
    EVENT_FLAG_FILEIO = EVENT_TRACE_FLAG_FILE_IO ,
    EVENT_FLAG_FILEIO_INIT = EVENT_TRACE_FLAG_FILE_IO_INIT,
    EVENT_FLAG_DISPATCHER = EVENT_TRACE_FLAG_DISPATCHER,
    EVENT_FLAG_VIRTUAL_ALLOC = EVENT_TRACE_FLAG_VIRTUAL_ALLOC,
    EVENT_FLAG_VAMAP = EVENT_TRACE_FLAG_VAMAP,
    EVENT_FLAG_NOSYSCONFIG = EVENT_TRACE_FLAG_NO_SYSCONFIG,
    EVENT_FLAG_JOB = EVENT_TRACE_FLAG_JOB,
    EVENT_FLAG_DEBUG_EVENTS = EVENT_TRACE_FLAG_DEBUG_EVENTS,
}EVENT_FLAGS;

// {2D8CEFE3-5CEF-4E57-8590-1A83E81DE663}
DEFINE_GUID(EventTracePropertiesGuid, 
0x2d8cefe3, 0x5cef, 0x4e57, 0x85, 0x90, 0x1a, 0x83, 0xe8, 0x1d, 0xe6, 0x63);

class CEventTracer
{
private:
    EVENT_FLAGS m_EventType;
    PEVENT_TRACE_PROPERTIES m_lpEventTraceProperties;
    TRACEHANDLE m_hSessionTrace;
    TRACEHANDLE m_hEtwTrace;
    HANDLE m_hThread;

public:
    CEventTracer();
    ~CEventTracer();

    CEventTracer(const CEventTracer&) = delete;
    CEventTracer& operator=(const CEventTracer&) = delete;

public:
    void AddEventType(IN int Type);
    ULONG SetEventFlags();
    BOOL StartEventTrace(IN LPCTSTR lpInstanceName);
    void StopEventTrace();
};
